package com.dingding.transfer.stamper.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dingding.transfer.stamper.constant.EventSubscribePara;
import com.dingding.transfer.stamper.constant.StamperEnum;
import com.dingding.transfer.stamper.constant.StamperPara;
import com.dingding.transfer.stamper.constant.StamperUrl;
import com.dingding.transfer.stamper.dto.BaseResult;
import com.dingding.transfer.stamper.dto.BaseResultFactory;
import com.dingding.transfer.stamper.dto.DeptInfo;
import com.dingding.transfer.stamper.dto.ReqEntity;
import com.dingding.transfer.stamper.entity.CompInfo;
import com.dingding.transfer.stamper.handler.CmdStrategyFactory;
import com.dingding.transfer.stamper.listener.ContextRefreshedListener;
import com.dingding.transfer.stamper.service.BusinessService;
import com.dingding.transfer.stamper.service.CallBackService;
import com.dingding.transfer.stamper.service.CmdStrategy;
import com.dingding.transfer.stamper.util.AESUtil;
import com.dingding.transfer.stamper.util.DingCallbackCrypto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Semaphore;

/**
 * @author wangxiyuan
 * @description 钉钉审批完成后回调接口
 * @createDate 2021/3/30 10:35
 **/
@RestController
@RequestMapping("/callback")
@Api(value = "回调模块")
@Slf4j
public class CallBackController {
    @Autowired
    private CallBackService callBackService;

    @Autowired
    private EventSubscribePara eventSubscribePara;

    @Autowired
    private ContextRefreshedListener contextRefreshedListener;

    @Autowired
    private StamperPara stamperPara;

    @Autowired
    private BusinessService businessService;

    private static final Semaphore semaphore = new Semaphore(30);

    /**
     *
     * @param msg_signature
     * @param timeStamp
     * @param nonce
     * @param json
     * @return
     */
    @PostMapping
    public Map<String, String> callBack(
            @RequestParam(value = "msg_signature", required = false) String msg_signature,
            @RequestParam(value = "timestamp", required = false) String timeStamp,
            @RequestParam(value = "nonce", required = false) String nonce,
            @RequestBody(required = false) JSONObject json) {

        try{
            semaphore.acquire();
            DingCallbackCrypto callbackCrypto = new DingCallbackCrypto(eventSubscribePara.getToken(),
                    eventSubscribePara.getAesKey()/*, eventSubscribePara.getAppKey()*/);
            // 使用加解密类型
            String encryptMsg = json.getString("encrypt");
            final String decryptMsg = callbackCrypto.getDecryptMsg(msg_signature, timeStamp, nonce, encryptMsg);
            // 反序列化回调事件json数据
            JSONObject eventJson = JSON.parseObject(decryptMsg);
            log.info("回调内容为{}",eventJson.toString());
            return callBackService.callBack(callbackCrypto,eventJson);
        }catch (Exception e){
            log.error("事件回调接口出现错误{}",e.getMessage());
        }finally {
            semaphore.release();
        }
        return null;
    }


    @GetMapping
    @ApiOperation(value = "手动调用同步部门以及用户信息")
    public BaseResult<?> manualCallBack(String compId){
        try {
            CompInfo compInfo = businessService.getCompInfo(compId);
            List<DeptInfo> deptInfos = contextRefreshedListener.getDeptInfos("1", compInfo);
            Set<DeptInfo> set = new HashSet<>();
            set.addAll(deptInfos);
            for (DeptInfo deptInfo :
                    set) {
                // 获取所有员工
                contextRefreshedListener.getUserInfos(deptInfo.getDeptId().toString(),compInfo);
            }
        } catch (Exception e) {
            log.error("手动调用钉钉获取部门用户信息失败",e.getMessage());
            return BaseResultFactory.produceError();
        }
        return BaseResultFactory.produceSuccess();
    }

    @PostMapping("/device")
    public BaseResult receive(@RequestBody ReqEntity param) {
        String uuid = param.getUuid();
        int cmd = param.getCmd();
        String data = param.getData();
        //如果开启了数据加密，回调的data参数需要先进行解密处理
        if (StamperUrl.isEncrypt) {
            data = AESUtil.decode(stamperPara.getAppsecret(), data);
        }
        log.debug("cmd为{},UUID为{},数据为{}", StamperEnum.getType(cmd),uuid,data);
        CmdStrategy cmdStrategy = CmdStrategyFactory.getCmdStrategy(cmd);
        return cmdStrategy.parse(cmd,data);
    }
}
